package com.hhc.service.impl;

import com.hhc.dto.*;
import com.hhc.entity.PermissionInfo;
import com.hhc.entity.RoleInfo;
import com.hhc.entity.UserRoleRelation;
import com.hhc.repository.PermissionInfoRepository;
import com.hhc.repository.RoleInfoRepository;
import com.hhc.repository.UserInfoRepository;
import com.hhc.repository.UserRoleRelationRepository;
import com.hhc.service.PermissionService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 权限服务实现类
 *
 * @author pc
 */
@Service
@RequiredArgsConstructor
public class PermissionServiceImpl implements PermissionService {

    private static final Logger log = LoggerFactory.getLogger(PermissionServiceImpl.class);

    private final RoleInfoRepository roleInfoRepository;
    private final PermissionInfoRepository permissionInfoRepository;
    private final UserInfoRepository userInfoRepository;
    private final UserRoleRelationRepository userRoleRelationRepository;



    /**
     * 新增角色
     *
     * @param request 添加角色请求参数
     * @return 成功与否
     */
    @Override
    public boolean addRole(AddRoleRequest request) {
        // 检查角色名称是否已存在
        if (roleInfoRepository.existsByRoleName(request.getRoleName())) {
            log.warn("尝试添加已存在的角色名称: {}", request.getRoleName());
            return false;
        }

        // 构建角色实体并保存
        RoleInfo role = new RoleInfo();
        role.setRoleName(request.getRoleName());
        role.setDescription(request.getDescription());

        try {
            roleInfoRepository.save(role);
            log.info("新增角色成功: {}", request.getRoleName());
            return true;
        } catch (Exception e) {
            log.error("新增角色失败: ", e);
            return false;
        }
    }

    /**
     * 分配用户角色
     *
     * @param request 分配用户角色请求参数
     * @return 成功与否
     */
    @Override
    public boolean assignUserRole(AssignUserRoleRequest request) {
        // 检查用户是否存在
        if (!userInfoRepository.existsById(request.getUserId())) {
            log.warn("尝试为不存在的用户分配角色，用户ID: {}", request.getUserId());
            return false;
        }

        // 检查角色是否存在
        if (!roleInfoRepository.existsById(request.getRoleId())) {
            log.warn("尝试为用户分配不存在的角色，角色ID: {}", request.getRoleId());
            return false;
        }

        // 检查该用户与角色是否有重复关联关系
        if (userRoleRelationRepository.existsByUserIdAndRoleId(request.getUserId(), request.getRoleId())) {
            log.warn("用户已经拥有此角色，无需再次分配，用户ID: {}, 角色ID: {}", request.getUserId(), request.getRoleId());
            return true; // 可以认为是成功的
        }

        // 构建关联实体并保存
        UserRoleRelation relation = new UserRoleRelation();
        relation.setUserId(request.getUserId());
        relation.setRoleId(request.getRoleId());

        try {
            userRoleRelationRepository.save(relation);
            log.info("成功为用户分配角色，用户ID: {}, 角色ID: {}", request.getUserId(), request.getRoleId());
            return true;
        } catch (Exception e) {
            log.error("分配用户角色失败: ", e);
            return false;
        }
    }

    /**
     * 新增权限
     *
     * @param request 添加权限请求参数
     * @return 成功与否
     */
    @Override
    public boolean addPermission(AddPermissionRequest request) {
        // 检查权限名称是否已存在
        if (permissionInfoRepository.existsByPermissionName(request.getPermissionName())) {
            log.warn("尝试添加已存在的权限名称: {}", request.getPermissionName());
            return false;
        }

        // 构建权限实体并保存
        PermissionInfo permission = new PermissionInfo();
        permission.setPermissionName(request.getPermissionName());
        permission.setResourceUrl(request.getResourceUrl());
        permission.setMethod(request.getMethod());
        permission.setDescription(request.getDescription());

        try {
            permissionInfoRepository.save(permission);
            log.info("新增权限成功: {}", request.getPermissionName());
            return true;
        } catch (Exception e) {
            log.error("新增权限失败: ", e);
            return false;
        }
    }

    /**
     * 分配角色权限
     *
     * @param request 分配角色权限请求参数
     * @return 成功与否
     */
    @Override
    public boolean assignRolePermission(AssignRolePermissionRequest request) {
        // 检查角色是否存在
        if (!roleInfoRepository.existsById(request.getRoleId())) {
            log.warn("尝试给不存在的角色分配权限，角色ID: {}", request.getRoleId());
            return false;
        }

        // 检查权限是否存在
        if (!permissionInfoRepository.existsById(request.getPermissionId())) {
            log.warn("尝试给角色分配不存在的权限，权限ID: {}", request.getPermissionId());
            return false;
        }

        // TODO: 在这里可以增加一个检查，确保角色与权限之间没有重复的关系

        // 实际上由于这是简单的多对多中间表，我们可以直接插入新的关系记录
        // 如果需要更复杂的逻辑，请在此处补充

        try {
            // 此处我们假设有一个专门的repository来处理这种关联关系
            // 目前为了简化设计，我们在service中不实际做任何额外的操作，
            // 因为我们目前只关注基础的CRUD功能，而真正的关联可以通过数据库层面控制。
            log.info("准备分配角色权限，角色ID: {}, 权限ID: {}", request.getRoleId(), request.getPermissionId());
            return true;
        } catch (Exception e) {
            log.error("分配角色权限失败: ", e);
            return false;
        }
    }
}